﻿using spaar.ModLoader;
using System;
using UnityEngine;
using spaar.ModLoader.UI;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;

namespace BesiegeDeformation
{
    public class BesiegeModLoader : Mod
    {
        public GameObject temp;

        public override string Author
        {
            get
            {
                return "TesseractCat, Modified by Orz_PX";
            }
        }

        public override bool CanBeUnloaded
        {
            get
            {
                return true;
            }
        }

        public override string DisplayName
        {
            get
            {
                return "Deformation Mod";
            }
        }

        public override string Name
        {
            get
            {
                return "BesiegeDeformationMod";
            }
        }

        public override Version Version
        {
            get
            {
                return new Version(0, 8);
            }
        }

        public BesiegeModLoader()
        {
        }

        public override void OnLoad()
        {
            GameObject gameObject = new GameObject();
            gameObject.AddComponent<BesiegeDeformationMod>();
            GameObject.DontDestroyOnLoad(gameObject);
        }

        public override void OnUnload()
        {
            GameObject.Destroy(this.temp);
        }
    }

    public class BesiegeDeformationMod : MonoBehaviour
    {
        private GameObject terrainObject = new GameObject();
        public static TerrainData terrain;
        public static GameObject terrainFinal;
        public Rect rect = new Rect(20f, 20f, 250f, 320f);
        public int brushSize = 5;
        public int brushSpeed = 1;
        public int brushHeight = 0;
        public int brushType = 1;
        public string modifierKeyUp = "1";
        public string modifierKeyDown = "2";
        public string saveText = "Untitled Terrain";
        public string loadText = "Untitled Terrain";

        static BesiegeDeformationMod()
        {
            BesiegeDeformationMod.terrain = new TerrainData();
            BesiegeDeformationMod.terrainFinal = new GameObject();
        }

        public BesiegeDeformationMod()
        {
        }

        private void DoMyWindow(int windowID)
        {
            BinaryFormatter binaryFormatter;
            FileStream fileStream;
            GUILayout.BeginHorizontal(new GUILayoutOption[0]);
            GUILayout.Label("Brush Size: ", new GUILayoutOption[0]);
            this.brushSize = int.Parse(GUILayout.TextField(this.brushSize.ToString(), new GUILayoutOption[0]));
            GUILayout.EndHorizontal();
            if (this.brushType == 1)
            {
                GUILayout.BeginHorizontal(new GUILayoutOption[0]);
                GUILayout.Label("Brush Speed: ", new GUILayoutOption[0]);
                this.brushSpeed = int.Parse(GUILayout.TextField(this.brushSpeed.ToString(), new GUILayoutOption[0]));
                GUILayout.EndHorizontal();
            }
            else if (this.brushType == 2)
            {
                GUILayout.BeginHorizontal(new GUILayoutOption[0]);
                GUILayout.Label("Brush Height: ", new GUILayoutOption[0]);
                this.brushHeight = int.Parse(GUILayout.TextField(this.brushHeight.ToString(), new GUILayoutOption[0]));
                GUILayout.EndHorizontal();
            }
            if (this.brushType == 1)
            {
                GUILayout.BeginHorizontal(new GUILayoutOption[0]);
                GUILayout.Label("Raise Ground = Ctrl + ", new GUILayoutOption[0]);
                this.modifierKeyUp = GUILayout.TextField(this.modifierKeyUp, 1, new GUILayoutOption[0]);
                GUILayout.EndHorizontal();
                GUILayout.BeginHorizontal(new GUILayoutOption[0]);
                GUILayout.Label("Lower Ground = Ctrl + ", new GUILayoutOption[0]);
                this.modifierKeyDown = GUILayout.TextField(this.modifierKeyDown, 1, new GUILayoutOption[0]);
                GUILayout.EndHorizontal();
            }
            else if (this.brushType == 2)
            {
                GUILayout.BeginHorizontal(new GUILayoutOption[0]);
                GUILayout.Label("Set Ground To Height = Ctrl + ", new GUILayoutOption[0]);
                this.modifierKeyUp = GUILayout.TextField(this.modifierKeyUp, 1, new GUILayoutOption[0]);
                GUILayout.EndHorizontal();
            }
            if (GUILayout.Button("Reset Ground", new GUILayoutOption[0]))
            {
                float[,] heights = BesiegeDeformationMod.terrain.GetHeights(0, 0, BesiegeDeformationMod.terrain.heightmapWidth, BesiegeDeformationMod.terrain.heightmapHeight);
                for (int i = 0; i < BesiegeDeformationMod.terrain.heightmapWidth; i++)
                {
                    for (int j = 0; j < BesiegeDeformationMod.terrain.heightmapHeight; j++)
                    {
                        heights[i, j] = 0.5f;
                    }
                }
                BesiegeDeformationMod.terrain.SetHeights(0, 0, heights);
            }
            if (this.brushType == 1)
            {
                if (GUILayout.Button("Change To Height Brush", new GUILayoutOption[0]))
                {
                    this.brushType = 2;
                }
            }
            else if (this.brushType == 2)
            {
                if (GUILayout.Button("Change To Deformation Brush", new GUILayoutOption[0]))
                {
                    this.brushType = 1;
                }
            }
            GUILayout.BeginHorizontal(new GUILayoutOption[0]);
            if (GUILayout.Button("Save Terrain", new GUILayoutOption[0]))
            {
                binaryFormatter = new BinaryFormatter();
                fileStream = new FileStream(string.Concat(Application.dataPath, "/Mods/", this.saveText, ".dat"), FileMode.Create);
                binaryFormatter.Serialize(fileStream, BesiegeDeformationMod.terrain.GetHeights(0, 0, BesiegeDeformationMod.terrain.heightmapWidth, BesiegeDeformationMod.terrain.heightmapHeight));
            }
            this.saveText = GUILayout.TextField(this.saveText, new GUILayoutOption[0]);
            GUILayout.EndHorizontal();
            GUILayout.BeginHorizontal(new GUILayoutOption[0]);
            if (GUILayout.Button("Load Terrain", new GUILayoutOption[0]))
            {
                binaryFormatter = new BinaryFormatter();
                fileStream = new FileStream(string.Concat(Application.dataPath, "/Mods/", this.loadText, ".dat"), FileMode.Open);
                float[,] singleArray = (float[,])binaryFormatter.Deserialize(fileStream);
                BesiegeDeformationMod.terrain.SetHeights(0, 0, singleArray);
            }
            this.loadText = GUILayout.TextField(this.loadText, new GUILayoutOption[0]);
            GUILayout.EndHorizontal();
            GUI.DragWindow();
        }

        private void OnGUI()
        {
            GUI.skin = ModGUI.Skin;
            this.rect = GUI.Window(-3027, this.rect, new GUI.WindowFunction(DoMyWindow), "Besiege Deformation Settings");
        }

        private void OnLevelWasLoaded(int level)
        {
            this.terrainObject = new GameObject();
            BesiegeDeformationMod.terrain = new TerrainData();
            BesiegeDeformationMod.terrainFinal = new GameObject();

            if (GameObject.Find("FloorBig"))
            {
                NewFloor();
            }
        }

        private void Start()
        {
        }

        private void Update()
        {
            float[,] heights;
            int i, j, xCoord, zCoord;
            bool flag;
            bool flag1;
            bool flag2;
            RaycastHit raycastHit = new RaycastHit();
            if ((GameObject.Find("NewFloorBig") ? false : GameObject.Find("FloorBig")))
            {
                NewFloor();
            }
            if (this.brushType == 1)
            {
                if (!Input.GetKey(KeyCode.LeftControl) || !Input.GetKey(this.modifierKeyUp))
                {
                    flag1 = (!Input.GetKey(KeyCode.RightControl) ? true : !Input.GetKey(this.modifierKeyUp));
                }
                else
                {
                    flag1 = false;
                }
                if (!flag1)
                {
                    if (Physics.Raycast(Camera.main.ScreenPointToRay(Input.mousePosition), out raycastHit))
                    {
                        xCoord = Mathf.RoundToInt((raycastHit.point.x - BesiegeDeformationMod.terrainFinal.transform.position.x) / BesiegeDeformationMod.terrain.size.x * (float)BesiegeDeformationMod.terrain.heightmapWidth);
                        zCoord = Mathf.RoundToInt((raycastHit.point.z - BesiegeDeformationMod.terrainFinal.transform.position.z) / BesiegeDeformationMod.terrain.size.z * (float)BesiegeDeformationMod.terrain.heightmapWidth);
                        heights = BesiegeDeformationMod.terrain.GetHeights(xCoord, zCoord, this.brushSize, this.brushSize);
                        for (i = 0; i < this.brushSize; i++)
                        {
                            for (j = 0; j < this.brushSize; j++)
                            {
                                heights[i, j] = heights[i, j] + 0.001f * (float)this.brushSpeed;
                            }
                        }
                        BesiegeDeformationMod.terrain.SetHeights(xCoord, zCoord, heights);
                    }
                }
                if (!Input.GetKey(KeyCode.LeftControl) || !Input.GetKey(this.modifierKeyDown))
                {
                    flag2 = (!Input.GetKey(KeyCode.RightControl) ? true : !Input.GetKey(this.modifierKeyDown));
                }
                else
                {
                    flag2 = false;
                }
                if (!flag2)
                {
                    if (Physics.Raycast(Camera.main.ScreenPointToRay(Input.mousePosition), out raycastHit))
                    {
                        xCoord = Mathf.RoundToInt((raycastHit.point.x - BesiegeDeformationMod.terrainFinal.transform.position.x) / BesiegeDeformationMod.terrain.size.x * (float)BesiegeDeformationMod.terrain.heightmapWidth);
                        zCoord = Mathf.RoundToInt((raycastHit.point.z - BesiegeDeformationMod.terrainFinal.transform.position.z) / BesiegeDeformationMod.terrain.size.z * (float)BesiegeDeformationMod.terrain.heightmapWidth);
                        heights = BesiegeDeformationMod.terrain.GetHeights(xCoord, zCoord, this.brushSize, this.brushSize);
                        for (i = 0; i < this.brushSize; i++)
                        {
                            for (j = 0; j < this.brushSize; j++)
                            {
                                heights[i, j] = heights[i, j] - 0.001f * (float)this.brushSpeed;
                            }
                        }
                        BesiegeDeformationMod.terrain.SetHeights(xCoord, zCoord, heights);
                    }
                }
            }
            else if (this.brushType == 2)
            {
                if (!Input.GetKey(KeyCode.LeftControl) || !Input.GetKey(this.modifierKeyUp))
                {
                    flag = (!Input.GetKey(KeyCode.RightControl) ? true : !Input.GetKey(this.modifierKeyUp));
                }
                else
                {
                    flag = false;
                }
                if (!flag)
                {
                    if (Physics.Raycast(Camera.main.ScreenPointToRay(Input.mousePosition), out raycastHit))
                    {
                        xCoord = Mathf.RoundToInt((raycastHit.point.x - BesiegeDeformationMod.terrainFinal.transform.position.x) / BesiegeDeformationMod.terrain.size.x * (float)BesiegeDeformationMod.terrain.heightmapWidth);
                        zCoord = Mathf.RoundToInt((raycastHit.point.z - BesiegeDeformationMod.terrainFinal.transform.position.z) / BesiegeDeformationMod.terrain.size.z * (float)BesiegeDeformationMod.terrain.heightmapWidth);
                        heights = BesiegeDeformationMod.terrain.GetHeights(xCoord, zCoord, this.brushSize, this.brushSize);
                        for (i = 0; i < this.brushSize; i++)
                        {
                            for (j = 0; j < this.brushSize; j++)
                            {
                                heights[i, j] = 0.5f;
                                heights[i, j] = heights[i, j] + 0.001f * (float)this.brushHeight;
                            }
                        }
                        BesiegeDeformationMod.terrain.SetHeights(xCoord, zCoord, heights);
                    }
                }
            }
        }

        private void NewFloor()
        {
            this.terrainObject = Terrain.CreateTerrainGameObject(BesiegeDeformationMod.terrain);
            TerrainData terrainDatum = BesiegeDeformationMod.terrain;
            terrainDatum.heightmapResolution = terrainDatum.heightmapResolution * 5;
            TerrainData terrainDatum1 = BesiegeDeformationMod.terrain;
            terrainDatum1.heightmapResolution = terrainDatum1.heightmapResolution * 2;

            GameObject gameObject = this.terrainObject;
            Vector3 vector3 = new Vector3(-300f, GameObject.Find("FloorPos").transform.position.y - 0.1f, -300f);
            Quaternion quaternion = new Quaternion();
            BesiegeDeformationMod.terrain.size = new Vector3(500f, 200f, 500f);

            BesiegeDeformationMod.terrainFinal = (GameObject)Instantiate(gameObject, vector3, quaternion);
            BesiegeDeformationMod.terrainFinal.name = "NewFloorBig";
            BesiegeDeformationMod.terrainFinal.GetComponent<Terrain>().materialType = Terrain.MaterialType.Custom;
            BesiegeDeformationMod.terrainFinal.GetComponent<Terrain>().materialTemplate = GameObject.Find("FloorBig").GetComponent<Renderer>().material;

            GameObject.Destroy(GameObject.Find("Terrain"));
            GameObject.Destroy(GameObject.Find("FloorBig"));

            BesiegeDeformationMod.terrainFinal.transform.Translate(new Vector3(0f, -100f, 0f));
            BesiegeDeformationMod.terrainFinal.AddComponent<OnCollisionMine>();

            float[,] heights = BesiegeDeformationMod.terrain.GetHeights(0, 0, BesiegeDeformationMod.terrain.heightmapWidth, BesiegeDeformationMod.terrain.heightmapHeight);
            for (int i = 0; i < BesiegeDeformationMod.terrain.heightmapWidth; i++)
            {
                for (int j = 0; j < BesiegeDeformationMod.terrain.heightmapHeight; j++)
                {
                    heights[i, j] = 0.5f;
                }
            }
            BesiegeDeformationMod.terrain.SetHeights(0, 0, heights);

            
        }
    }

    public class OnCollisionMine : MonoBehaviour
    {
        public OnCollisionMine()
        {
        }

        private void OnCollisionEnter(Collision c)
        {
            try
            {
                if (c.transform.GetComponent<MyBlockInfo>().blockName == "DRILL")
                {
                    int num = Mathf.RoundToInt((c.transform.position.x - BesiegeDeformationMod.terrainFinal.transform.position.x) / BesiegeDeformationMod.terrain.size.x * (float)BesiegeDeformationMod.terrain.heightmapWidth);
                    int num1 = Mathf.RoundToInt((c.transform.position.z - BesiegeDeformationMod.terrainFinal.transform.position.z) / BesiegeDeformationMod.terrain.size.z * (float)BesiegeDeformationMod.terrain.heightmapWidth);
                    float[,] heights = BesiegeDeformationMod.terrain.GetHeights(num, num1, 3, 3);
                    for (int i = 0; i < 3; i++)
                    {
                        for (int j = 0; j < 3; j++)
                        {
                            heights[i, j] = heights[i, j] - 0.005f;
                        }
                    }
                    BesiegeDeformationMod.terrain.SetHeights(num, num1, heights);
                }
            }
            catch
            {
            }
        }
    }
}
